home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / arcers / tarsrc.zip / TARSRC.TAR / tar-1.11.2 / mangle.c < prev    next >
C/C++ Source or Header  |  1993-11-15  |  7KB  |  280 lines

  1. /* mangle.c -- encode long filenames
  2.    Copyright (C) 1988, 1992 Free Software Foundation
  3.  
  4. This file is part of GNU Tar.
  5.  
  6. GNU Tar is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU Tar is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Tar; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdio.h>
  21. #include <sys/types.h>
  22. #include <time.h>
  23.  
  24. #include "tar.h"
  25. #include "port.h"
  26.  
  27. #ifndef USE_PROTOTYPES
  28. time_t time ();
  29. #endif
  30.  
  31. #ifndef USE_PROTOTYPES
  32. void add_buffer ();
  33. extern PTR ck_malloc ();
  34. void finish_header ();
  35. extern PTR init_buffer ();
  36. extern char *quote_copy_string ();
  37. extern char *get_buffer ();
  38. char *un_quote_string ();
  39.  
  40. extern union record *start_header ();
  41. #else
  42. #include "mangle_p.h"
  43. #include "port_p.h"
  44. #include "buffer_p.h"
  45. #endif
  46.  
  47. extern struct stat hstat;    /* Stat struct corresponding */
  48.  
  49. struct mangled
  50.   {
  51.     struct mangled *next;
  52.     int type;
  53.     char mangled[NAMSIZ];
  54.     char *linked_to;
  55.     char normal[1];
  56.   };
  57.  
  58.  
  59. /* Should use a hash table, etc. .  */
  60. struct mangled *first_mangle;
  61. int mangled_num = 0;
  62.  
  63. #if 0                /* Deleted because there is now a better way to do all this */
  64.  
  65. char *
  66. find_mangled (name)
  67.      char *name;
  68. {
  69.   struct mangled *munge;
  70.  
  71.   for (munge = first_mangle; munge; munge = munge->next)
  72.     if (!strcmp (name, munge->normal))
  73.       return munge->mangled;
  74.   return 0;
  75. }
  76.  
  77.  
  78. #ifdef S_ISLNK
  79. void
  80. add_symlink_mangle (symlink, linkto, buffer)
  81.      char *symlink;
  82.      char *linkto;
  83.      char *buffer;
  84. {
  85.   struct mangled *munge, *kludge;
  86.  
  87.   munge = (struct mangled *) ck_malloc (sizeof (struct mangled) + strlen (symlink) + strlen (linkto) + 2);
  88.   if (!first_mangle)
  89.     first_mangle = munge;
  90.   else
  91.     {
  92.       for (kludge = first_mangle; kludge->next; kludge = kludge->next)
  93.     ;
  94.       kludge->next = munge;
  95.     }
  96.   munge->type = 1;
  97.   munge->next = 0;
  98.   strcpy (munge->normal, symlink);
  99.   munge->linked_to = munge->normal + strlen (symlink) + 1;
  100.   strcpy (munge->linked_to, linkto);
  101.   sprintf (munge->mangled, "@@MaNgLeD.%d", mangled_num++);
  102.   strncpy (buffer, munge->mangled, NAMSIZ);
  103. }
  104.  
  105. #endif
  106.  
  107. void
  108. add_mangle (name, buffer)
  109.      char *name;
  110.      char *buffer;
  111. {
  112.   struct mangled *munge, *kludge;
  113.  
  114.   munge = (struct mangled *) ck_malloc (sizeof (struct mangled) + strlen (name));
  115.   if (!first_mangle)
  116.     first_mangle = munge;
  117.   else
  118.     {
  119.       for (kludge = first_mangle; kludge->next; kludge = kludge->next)
  120.     ;
  121.       kludge->next = munge;
  122.     }
  123.   munge->next = 0;
  124.   munge->type = 0;
  125.   strcpy (munge->normal, name);
  126.   sprintf (munge->mangled, "@@MaNgLeD.%d", mangled_num++);
  127.   strncpy (buffer, munge->mangled, NAMSIZ);
  128. }
  129.  
  130. void
  131. write_mangled ()
  132. {
  133.   struct mangled *munge;
  134.   struct stat hstat;
  135.   union record *header;
  136.   char *ptr1, *ptr2;
  137.   PTR the_buffer;
  138.   int size;
  139.   int bufsize;
  140.  
  141.   if (!first_mangle)
  142.     return;
  143.   the_buffer = init_buffer ();
  144.   for (munge = first_mangle, size = 0; munge; munge = munge->next)
  145.     {
  146.       ptr1 = quote_copy_string (munge->normal);
  147.       if (!ptr1)
  148.     ptr1 = munge->normal;
  149.       if (munge->type)
  150.     {
  151.       add_buffer (the_buffer, "Symlink ", 8);
  152.       add_buffer (the_buffer, ptr1, strlen (ptr1));
  153.       add_buffer (the_buffer, " to ", 4);
  154.  
  155.       if (ptr2 = quote_copy_string (munge->linked_to))
  156.         {
  157.           add_buffer (the_buffer, ptr2, strlen (ptr2));
  158.           free (ptr2);
  159.         }
  160.       else
  161.         add_buffer (the_buffer, munge->linked_to, strlen (munge->linked_to));
  162.     }
  163.       else
  164.     {
  165.       add_buffer (the_buffer, "Rename ", 7);
  166.       add_buffer (the_buffer, munge->mangled, strlen (munge->mangled));
  167.       add_buffer (the_buffer, " to ", 4);
  168.       add_buffer (the_buffer, ptr1, strlen (ptr1));
  169.     }
  170.       add_buffer (the_buffer, "\n", 1);
  171.       if (ptr1 != munge->normal)
  172.     free (ptr1);
  173.     }
  174.  
  175.   bzero (&hstat, sizeof (struct stat));
  176.   hstat.st_atime = hstat.st_mtime = hstat.st_ctime = time (0);
  177.   ptr1 = get_buffer (the_buffer);
  178.   hstat.st_size = strlen (ptr1);
  179.  
  180.   header = start_header ("././@MaNgLeD_NaMeS", &hstat);
  181.   header->header.linkflag = LF_NAMES;
  182.   finish_header (header);
  183.   size = hstat.st_size;
  184.   header = findrec ();
  185.   bufsize = endofrecs ()->charptr - header->charptr;
  186.  
  187.   while (bufsize < size)
  188.     {
  189.       bcopy (ptr1, header->charptr, bufsize);
  190.       ptr1 += bufsize;
  191.       size -= bufsize;
  192.       userec (header + (bufsize - 1) / RECORDSIZE);
  193.       header = findrec ();
  194.       bufsize = endofrecs ()->charptr - header->charptr;
  195.     }
  196.   bcopy (ptr1, header->charptr, size);
  197.   bzero (header->charptr + size, bufsize - size);
  198.   userec (header + (size - 1) / RECORDSIZE);
  199. }
  200.  
  201. #endif
  202.  
  203. void
  204. extract_mangle (head)
  205.      union record *head;
  206. {
  207.   char *buf;
  208.   char *fromtape;
  209.   char *to;
  210.   char *ptr, *ptrend;
  211.   char *nam1, *nam1end;
  212.   int size;
  213.   int copied;
  214.  
  215.   size = hstat.st_size;
  216.   buf = to = ck_malloc (size + 1);
  217.   buf[size] = '\0';
  218.   while (size > 0)
  219.     {
  220.       fromtape = findrec ()->charptr;
  221.       if (fromtape == 0)
  222.     {
  223.       msg ("Unexpected EOF in mangled names!");
  224.       return;
  225.     }
  226.       copied = endofrecs ()->charptr - fromtape;
  227.       if (copied > size)
  228.     copied = size;
  229.       bcopy (fromtape, to, copied);
  230.       to += copied;
  231.       size -= copied;
  232.       userec ((union record *) (fromtape + copied - 1));
  233.     }
  234.   for (ptr = buf; *ptr; ptr = ptrend)
  235.     {
  236.       ptrend = index (ptr, '\n');
  237.       *ptrend++ = '\0';
  238.  
  239.       if (!strncmp (ptr, "Rename ", 7))
  240.     {
  241.       nam1 = ptr + 7;
  242.       nam1end = index (nam1, ' ');
  243.       while (strncmp (nam1end, " to ", 4))
  244.         {
  245.           nam1end++;
  246.           nam1end = index (nam1end, ' ');
  247.         }
  248.       *nam1end = '\0';
  249.       if (ptrend[-2] == '/')
  250.         ptrend[-2] = '\0';
  251.       un_quote_string (nam1end + 4);
  252.       if (rename (nam1, nam1end + 4))
  253.         msg_perror ("Can't rename %s to %s", nam1, nam1end + 4);
  254.       else if (f_verbose)
  255.         msg ("Renamed %s to %s", nam1, nam1end + 4);
  256.     }
  257. #ifdef S_ISLNK
  258.       else if (!strncmp (ptr, "Symlink ", 8))
  259.     {
  260.       nam1 = ptr + 8;
  261.       nam1end = index (nam1, ' ');
  262.       while (strncmp (nam1end, " to ", 4))
  263.         {
  264.           nam1end++;
  265.           nam1end = index (nam1end, ' ');
  266.         }
  267.       *nam1end = '\0';
  268.       un_quote_string (nam1);
  269.       un_quote_string (nam1end + 4);
  270.       if (symlink (nam1, nam1end + 4) && (unlink (nam1end + 4) || symlink (nam1, nam1end + 4)))
  271.         msg_perror ("Can't symlink %s to %s", nam1, nam1end + 4);
  272.       else if (f_verbose)
  273.         msg ("Symlinkd %s to %s", nam1, nam1end + 4);
  274.     }
  275. #endif
  276.       else
  277.     msg ("Unknown demangling command %s", ptr);
  278.     }
  279. }
  280.